/*
 * cmm9801.c qkd发送端程序
 *
 *  Created on: 2018年11月17日
 *      Author: Administrator
 */
#include <time.h>

#include "cgic.h"
#include "conf.h"
#include "board.h"
#include "pl.h"
#include "cdma.h"
#include <sys/sysinfo.h>

#define FNAME "./conf.ini"
#define SERVER_NAME cgiServerName
#define CGI_COOKIE "cgi_cookie"

/*
 * 登录信息结构体，记录登录用户名与登录时间，
 */
struct logininfo {
	char userName[1024];
	char loginTime[64];
};

/*
 * 登陆
 */
void login();

/*
 * 登出
 */
void logout();

/*
 * 检查是否登陆
 */
int check_login();

/*
 * 读取cookie
 */
void cookie_read();

/*
 * 设置cookie
 */
int cookie_set();

/*
 * 随机产生字符串
 */
void random_key();

/*
 * 主页面数据加载
 */
void main_load();

/*
 * 设备信息数据加载
 */
void sbxx_load();

/*
 * 设备设置数据加载
 */
void sbsz_load();

/*
 * 设备设置
 */
void sbsz_set();

/*
 * 登陆失败
 */
void login_fail();

/*
 * 操作成功
 */
void op_success();

/*
 * 操作失败
 */
void op_fail();

/*
 * 用户名和密码设置
 */
void uname_upass_set();

/*
 * 存储登录信息
 */
void write_login_info();

/*
 * 读取登录信息
 */
struct logininfo * read_login_info();

/*
 * 校验用户名与密码，用于非浏览器端的校验。
 */
void verify();

/*
 *获取当前系统时间
 */
void get_current_time(char time_str[], int n);
/*
 * 获取系统运行时间
 */
void sys_info(long * uptime);

/*
 * 请求密钥
 */
void req_skey();

/*
 * 执行函数
 */
int cgiMain() {
	/**
	 * ------------------------------------------------
	 * operateType:
	 * 		登陆操作:
	 *			已登陆:
	 * 				跳转到主界面。
	 *			未登陆:
	 * 				做登陆处理。
	 * 		非登陆其他操作:
	 * 			未登陆:
	 * 				跳转到登陆界面。
	 * 			已登陆:
	 * 				操作处理。
	 * 		未知操作:
	 * 			跳转到主界面。
	 * ------------------------------------------------
	 */
	char optype[1024] = { 0 };

	cgiFormString("optype", optype, sizeof(optype));

	//	cgiHeaderContentType("text/html");

	//	fprintf(cgiOut, "optype:%s", optype);

	if (strcmp(optype, "login") == 0) {
		login();
	} else if (strcmp(optype, "verify") == 0) {
		verify();
	} else {
		if (check_login() == 0) {
			//重新设置cookie的超时时间。
			cookie_set();
			if (strcmp(optype, "logout") == 0) {
				logout();
			} else if (strcmp(optype, "main_load") == 0) {
				main_load();
			} else if (strcmp(optype, "sbxx_load") == 0) {
				sbxx_load();
			} else if (strcmp(optype, "sbsz_load") == 0) {
				sbsz_load();
			} else if (strcmp(optype, "sbsz_set") == 0) {
				sbsz_set();
			} else if (strcmp(optype, "uname_upass_set") == 0) {
				uname_upass_set();
			} else if (strcmp(optype, "req_skey") == 0) {
				req_skey();
			}
		} else {
			login_fail();
		}
	}
	return 0;
}

void login() {
	if (check_login() == 0) {
		/*
		 *已登陆，跳转到main界面
		 */
		cgiHeaderContentType("text/html");
		fprintf(cgiOut,
				"<body onLoad=\"javascript:sessionStorage.setItem('isLogin', 'true');parent.location='/main.html'\"/>");
		return;
	}
	char username[1024];
	char password[1024];

	char *uname;
	char *upass;

	cgiFormString("username", username, sizeof(username));
	cgiFormString("password", password, sizeof(password));
	//登录，需验证3次。第一次验证userName。
	readCFG(FNAME, "userName", &uname);
	readCFG(FNAME, "userPass", &upass);
	if (strcmp(username, strtok(uname, "\n")) == 0
			&& strcmp(password, strtok(upass, "\n")) == 0) {
		int ret = cookie_set();
		/*
		 * 登陆成功跳转到main界面,设置sessionStorage
		 */
		write_login_info(username);
		cgiHeaderContentType("text/html");
		if (ret == 0) {
			fprintf(cgiOut,
					"<body onLoad=\"javascript:sessionStorage.setItem('isLogin', 'true');parent.location='/main.html'\"/>");
			return;
		}
	}
	//第二次验证userName_1。
	readCFG(FNAME, "userName_1", &uname);
	readCFG(FNAME, "userPass_1", &upass);
	if (strcmp(username, strtok(uname, "\n")) == 0
			&& strcmp(password, strtok(upass, "\n")) == 0) {
		int ret = cookie_set();
		/*
		 * 登陆成功跳转到main界面,设置sessionStorage
		 */
		write_login_info(username);
		cgiHeaderContentType("text/html");
		if (ret == 0) {
			fprintf(cgiOut,
					"<body onLoad=\"javascript:sessionStorage.setItem('isLogin', 'true');parent.location='/main.html'\"/>");
			return;
		}
	}
	//第三次验证userName_2。
	readCFG(FNAME, "userName_2", &uname);
	readCFG(FNAME, "userPass_2", &upass);
	if (strcmp(username, strtok(uname, "\n")) == 0
			&& strcmp(password, strtok(upass, "\n")) == 0) {
		int ret = cookie_set();
		/*
		 * 登陆成功跳转到main界面,设置sessionStorage
		 */
		write_login_info(username);
		cgiHeaderContentType("text/html");
		if (ret == 0) {
			fprintf(cgiOut,
					"<body onLoad=\"javascript:sessionStorage.setItem('isLogin', 'true');parent.location='/main.html'\"/>");
			return;
		}
	}
	/*
	 *其他情况，跳转到登陆界面
	 */
	cgiHeaderContentType("text/html");
	fprintf(cgiOut,
			"<body onLoad=\"javascript:sessionStorage.setItem('isLogin', 'false');parent.location='/index.html'\"/>");
}

int check_login() {
	char cookieValue[1024] = { 0 };
	char *ckValue;
	cookie_read(CGI_COOKIE, cookieValue, 1024);
	readCFG(FNAME, CGI_COOKIE, &ckValue);
	if (strlen(cookieValue) == 0 || strlen(ckValue) == 0) {
		return -1;
	}
	return strcmp(cookieValue, strtok(ckValue, "\n"));
}

void cookie_read(char *key, char *val, int size) {
	char **array;
	if (cgiCookies(&array) != cgiFormSuccess) {
		return;
	}
	cgiCookieString(key, val, size);
	cgiStringArrayFree(array);
}

int cookie_set() {
	char str[10] = { 0 };
	random_key(str, 10);
	if (writeCFG(FNAME, CGI_COOKIE, str) == 0) {
		cgiHeaderCookieSetString(CGI_COOKIE, str, 300, cgiScriptName,
		SERVER_NAME);
		return 0;
	}
	return 1;
}

void random_key(char str[], int num) {
	int i;
	srand(time(NULL));
	for (i = 0; i < num; i++) {
		str[i] = rand() % (0x7a - 0x61) + 0x61;
	}
}

void logout() {
	cgiHeaderCookieSetString(CGI_COOKIE, "", 0, cgiScriptName, SERVER_NAME);
	cgiHeaderContentType("text/html");
	fprintf(cgiOut,
			"<body onLoad=\"javascript:sessionStorage.setItem('isLogin', 'false');parent.location='/index.html'\"/>");

}

void main_load() {
	struct logininfo *linfo;
	linfo = read_login_info();
	long * uptime;
	char time_str[64] = { 0 };
	long x = 0;
	uptime = &x;
	get_current_time(time_str, 64);
	sys_info(uptime);
	cgiHeaderContentType("text/json");
	//fprintf(cgiOut,	"{\"user\": {\"userName\": \"%s\",\"role\": \"admin\",\"id\": \"152352\"},\"address\": \"tianjin\",\"loginTime\": \"%s\",\"temperature\": 50,\"rate\": 200}",linfo->userName,linfo->loginTime);
	fprintf(cgiOut,
			"{\"user\": {\"userName\": \"%s\",\"role\": \"admin\",\"id\": \"152352\"},\"address\": \"tianjin\",\"loginTime\": \"%s\",\"temperature\": 50,\"rate\": 200,\"curtime\":  \"%s\",\"uptime\": %ld}",
			linfo->userName, linfo->loginTime, time_str, *uptime);
	free(linfo);
}

void sbxx_load() {
	cgiHeaderContentType("text/json");
	fprintf(cgiOut,
			"{\"localIp\":\"192.168.1.1\",\"targetIp\":\"192.168.1.2\",\"runTime\":300000,\"currentKeyPool\": 90,\"useableKeyPool\":50}");
}
void sbsz_load() {
	cgiHeaderContentType("text/json");
	fprintf(cgiOut,
			"{\"port1_delay\":10,\"port2_delay\": 20,\"port3_delay\":30,\"port4_delay\": 40,\"port5_delay\":50,\"attenuation\":60}");
}
void sbsz_set() {

	int port_delay[5] = { 0 };
	int attenuation, ret, i;
	cgiFormInteger("port1_delay", &port_delay[0], 0);
	cgiFormInteger("port2_delay", &port_delay[1], 0);
	cgiFormInteger("port3_delay", &port_delay[2], 0);
	cgiFormInteger("port4_delay", &port_delay[3], 0);
	cgiFormInteger("port5_delay", &port_delay[4], 0);
	cgiFormInteger("attenuation", &attenuation, 0);
	/*
	 * 设置端口延时
	 */
	ret = board_init();
	//cgiHeaderContentType("text/html");
	//fprintf(cgiOut,"ret:%d",ret);
 	if (ret != 0) {
 		op_fail();
 		return;
 	}
 	for (i = 0; i < 5; ++i) {
 		// 设置延时
 		pldelay_set(1 << (i + 1), port_delay[i]);
 	}
 	// 设置衰减
 	plspi_write(attenuation);
 	board_exit();
 	op_success();
}

void login_fail() {
	cgiHeaderContentType("text/json");
	fprintf(cgiOut, "{\"login\":\"false\"}");
}

void op_success() {
	cgiHeaderContentType("text/json");
	fprintf(cgiOut, "{\"success\":\"true\"}");
}

void op_fail() {
	cgiHeaderContentType("text/json");
	fprintf(cgiOut, "{\"success\":\"false\"}");
}

void uname_upass_set() {
	char username[1024];
	char password[1024];
	cgiFormString("username", username, sizeof(username));
	cgiFormString("password", password, sizeof(password));
	if (strlen(username) != 0 && strlen(password) != 0) {
		writeCFG(FNAME, "userName", username);
		writeCFG(FNAME, "userPass", password);
	}
	logout();
}

void write_login_info(char * userName) {
	struct logininfo * linfo;
	FILE * fp;
	time_t t;
	linfo = (struct logininfo *) malloc(sizeof(struct logininfo));
	memset(linfo, 0, sizeof(*linfo));
	strcpy(linfo->userName, userName);
	time(&t);
	strftime(linfo->loginTime, sizeof(linfo->loginTime), "%Y/%m/%d %X",
			localtime(&t));
	if ((fp = fopen("logininfo.txt", "wb")) == NULL) {
		return;
	}
	fwrite(linfo, sizeof(struct logininfo), 1, fp);
	free(linfo);
	fclose(fp);
}

struct logininfo * read_login_info() {
	struct logininfo * linfo;
	FILE * fp;
	if ((fp = fopen("logininfo.txt", "rb")) == NULL) {
		return NULL;
	}
	linfo = (struct logininfo *) malloc(sizeof(struct logininfo));
	fread(linfo, sizeof(struct logininfo), 1, fp);
	fclose(fp);
	return linfo;
}

void verify() {
	char username[1024];
	char password[1024];

	char *uname;
	char *upass;

	cgiFormString("username", username, sizeof(username));
	cgiFormString("password", password, sizeof(password));

	readCFG(FNAME, "userName", &uname);
	readCFG(FNAME, "userPass", &upass);
	if (strcmp(username, strtok(uname, "\n")) == 0
			&& strcmp(password, strtok(upass, "\n")) == 0) {
		op_success();
		return;
	}
	readCFG(FNAME, "userName_1", &uname);
	readCFG(FNAME, "userPass_1", &upass);
	if (strcmp(username, strtok(uname, "\n")) == 0
			&& strcmp(password, strtok(upass, "\n")) == 0) {
		op_success();
		return;
	}
	readCFG(FNAME, "userName_2", &uname);
	readCFG(FNAME, "userPass_2", &upass);
	if (strcmp(username, strtok(uname, "\n")) == 0
			&& strcmp(password, strtok(upass, "\n")) == 0) {
		op_success();
		return;
	}
	op_fail();
}

void get_current_time(char time_str[], int n) {
	time_t t;
	time(&t);
	strftime(time_str, n, "%Y/%m/%d %X", localtime(&t));
}

void sys_info(long * uptime) {
	struct sysinfo info;
	if (!sysinfo(&info)) {
		*uptime = info.uptime;
	};
}

void req_skey(){
/*
	int skeyCount;
	cgiFormInteger("skeyCount",&skeyCount,0);

	int i = request_skey(skeyCount);
	fprintf(cgiOut,"sss%d",i);
	if (i==-1) {
		op_fail();
	}else{
		op_success();
	}
*/
	op_success();
}
